package com.itheima.mysort;

import java.util.Random;

public class A05_QuickSortDemo {
    public static void main(String[] args) {
         /*
        快速排序：
            第一轮：以0索引的数字为基准数，确定基准数在数组中正确的位置。
            比基准数小的全部在左边，比基准数大的全部在右边。
            后面以此类推。
      */

        //int[] arr = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8};

        int[] arr = new int[10000];

        Random r = new Random();
        for (int i = 0; i < arr.length; i++) {
            arr[i] = r.nextInt();
        }

        long start = System.currentTimeMillis();
        quickSort(arr, 0, arr.length - 1);
        long end = System.currentTimeMillis();

        System.out.println(end - start);

        //课堂练习：
        //我们可以利用相同的办法去测试一下，选择排序，冒泡排序以及插入排序运行的效率
        //得到一个结论：快速排序真的非常快

        //printArr(arr);
    }

    //参数一：我们要排序的数组
    //参数二：要排序数组的起始索引
    //参数三：要排序数组的结束索引
    public static void quickSort(int[] arr, int i, int j) {
        //定义两个变量记录要查找的范围
        int startIndex = i;
        int endIndex = j;

        if(startIndex >endIndex){
            //递归的出口
            return;
        }

        //定义基准数
        int baseNumber = arr[i];
        //利用循环找到要交换的数字
        while (startIndex != endIndex) {
            //利用end，从后往前开始找，找比基准数要小的数字
            while (true) {
                if (endIndex <= startIndex || arr[endIndex] < baseNumber) {
                    break;
                }
                endIndex--;
            }
            //利用start，从前往后开始找，找比基准数要大的数字
            while (true) {
                if (endIndex <= startIndex || arr[startIndex] > baseNumber) {
                    break;
                }
                startIndex++;
            }
            //把startIndex和endIndex指向的元素进行交换
            int tmp = arr[startIndex];
            arr[startIndex] = arr[endIndex];
            arr[endIndex] = tmp;
        }

        //当startIndex和endIndex指向了同一个元素的时候，那么上面的循环就会结束
        //表示已经找到了基准数在数组中应存入的位置
        //基准数归位
        //就是拿着这个范围中的第一个数字，跟startIndex指向的元素进行交换
        int tmp = arr[i];
        arr[i] = arr[startIndex];
        arr[startIndex] = tmp;

        //确定6左边的范围，重复刚刚所做的事情
        quickSort(arr,i,startIndex - 1);
        //确定6左边的范围，重复刚刚所做的事情
        quickSort(arr,startIndex + 1,j);
    }

    public static void printArr(int[] arr) {
        //3.遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}
